package work.base.jvm.method;

import org.openjdk.jol.vm.VM;
import work.entity.User;

/**
 * 关于数据类型
 *
 * 基础知识回顾
 * 1) 形参和实参
 *      形参是定义函数时使用的参数
 *      实参是调用函数时传入的参数
 * 2) 值传递和引用传递
 *      基本数据类型  值就直接保存在变量中              赋值运算符(也就是=)会直接改变变量的值, 原来的值被覆盖掉
 *      引用数据类型  变量中保存的只是实际对象的地址     赋值运算符改变引用中所保存的地址, 原来的对象不会被改变
 *      1 Java中其实还是值传递的, 只不过对于对象参数, 值的内容是对象的引用
 *      2 方法调用时, 实际参数把它的值传递给对应的形式参数, 函数接收的是原始值的一个copy,
 *          此时内存中存在两个相等的基本类型, 即实际参数和形式参数
 *          方法中的操作都是对形参这个值的修改, 不影响实际参数的值
 *          (对于基本类型 参数的值不变 对于引用类型 地址的值不会变)
 *      3 注意下
 *          String, 以及Integer、Double等几个基本类型包装类, 它们都是immutable类型
 *          因为没有提供自身修改的函数, 每次操作都是新生成一个对象 和基本数据相似
 *      PS
 *          VM.current().addressOf(user)可以查看对象的地址值
 *
 */
public class DataTypeMain {

    public static void main(String[] args) {
        DataTypeMain typeMain = new DataTypeMain();

        int b = 20;
        typeMain.changeInt(b);
        System.out.println(b);
        System.out.println("======");

        String str = "hello";
        typeMain.changeString(str);
        System.out.println(str);
        System.out.println("======");

        Integer int1 = 60;
        typeMain.changeInteger(int1);
        System.out.println(int1);
        System.out.println("======");


        // 获取对象的内存地址 证明 方法中的操作都是对形参这个值的修改, 不影响实际参数的值
        User user = new User("222","SML","高中");
        System.out.println("获取实际内存地址");
        System.out.println(VM.current().addressOf(user));
        typeMain.changeUser(user);
        System.out.println(user);
        System.out.println(VM.current().addressOf(user));

    }

    public void changeInt(int a) {
        a = 100;
        System.out.println(a);
    }

    public void changeInteger(Integer a) {
        a = 100;
        System.out.println(a);
    }

    public void changeUser(User user) {
        user.setName("Wang");
    }

    public void changeString(String str) {
        str = "AAAA";
    }
}
